package com.shawn.server.service;

import cn.hutool.core.collection.CollUtil;
import cn.hutool.db.DaoTemplate;
import com.shawn.commons.utils.CommentType;
import com.shawn.commons.utils.RC;
import com.shawn.dubbo.api.CommentsApi;
import com.shawn.dubbo.api.MovementApi;
import com.shawn.dubbo.api.UserInfoApi;
import com.shawn.model.entity.UserInfo;
import com.shawn.model.mongo.Comment;
import com.shawn.model.mongo.Movement;
import com.shawn.model.vo.CommentsVo;
import com.shawn.model.vo.ErrorResult;
import com.shawn.model.vo.PageResult;
import com.shawn.server.exception.BusinessException;
import com.shawn.server.interceptor.ThreadContext;
import lombok.Data;
import lombok.extern.slf4j.Slf4j;
import org.apache.dubbo.config.annotation.DubboReference;
import org.apache.dubbo.config.annotation.DubboService;
import org.bson.types.ObjectId;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.stereotype.Service;

import java.util.*;
import java.util.stream.Collectors;

@Slf4j
@Service
public class CommentsService {

    @DubboReference
    private CommentsApi commentsApi;

    @DubboReference
    private UserInfoApi userInfoApi;

    @DubboReference
    private MovementApi movementApi;

    @Autowired
    private RedisTemplate<String,String> redisTemplate;

    @Autowired
    private MqMessageService mqMessageService;


    /**
     * 根据动态/视频id得到所有评论
     *
     * @param id       动态id
     * @param page     页面
     * @param pageSize 页面大小
     * @return {@link PageResult}<{@link CommentsVo}>
     */
    public PageResult<CommentsVo> getAllComments(String id, Integer page, Integer pageSize) {

        //分页查询该条动态/视频下所有评论并按点赞数量及发布时间降序排序
        PageResult<Comment> pageResult = commentsApi.getAllComments(id,page,pageSize,CommentType.COMMENT);
        if (pageResult.getCounts()==0){
            return new PageResult<>();
        }
        Long userId = ThreadContext.getUserId();

        List<Comment> comments = pageResult.getItems();
        //获取所有评论用户id
        List<Long> commentIds = comments.stream().map(Comment::getUserId).collect(Collectors.toList());
        //调用服务根据id集合查询所有用户详情
       List<UserInfo> userInfoList = userInfoApi.findByIds(commentIds);
        Map<Long, UserInfo> infoMap = CollUtil.fieldValueMap(userInfoList, "id");
        List<CommentsVo> commentsVos = new ArrayList<>();
        String userHashKey = RC.COMMENT_LIKE_HASH_KEY+userId;
        for (Comment comment : comments) {
            String commentKey = RC.COMMENTS_INTERACT_KEY+comment.getId().toHexString();
            //判断该用户是否对当前评论进行点赞
            Boolean hasLike = redisTemplate.opsForHash().hasKey(commentKey, userHashKey);
            UserInfo userInfo = infoMap.get(comment.getUserId());
            CommentsVo commentsVo = CommentsVo.init(comment, userInfo);
            commentsVo.setHasLiked(hasLike?1:0);
            commentsVos.add(commentsVo);
        }
        return new PageResult<>(page,pageSize,pageResult.getCounts(),commentsVos);
    }

    /**
     * 发表评论
     *
     * @param movementId  运动id
     * @param commentType 注释类型
     * @param comment     评论
     */
    public void publishComments(String movementId,Integer commentType, String comment) {
        //构造评论
        Comment commentEntity = new Comment();
        commentEntity.setPublishId(new ObjectId(movementId));
        commentEntity.setCommentType(commentType);
        commentEntity.setContent(comment);
        commentEntity.setUserId(ThreadContext.getUserId());
        //根据动态id查找被评论人id
        Movement movement = movementApi.getById(movementId);
        commentEntity.setPublishUserId(movement.getUserId());
        commentEntity.setCreated(new Date().getTime());
        //todo 保存评论,同步更新点赞数,评论数,喜欢数
        //发送消息
        mqMessageService.sendLogMessage(Objects.requireNonNull(ThreadContext.getUserId()),"0205","movement",movementId);
        //保存
        commentsApi.saveComments(commentEntity);
    }

    /**
     * 评论是否喜欢
     *
     * @param userId 用户id
     * @param id     id
     * @param isLike 就像
     * @return {@link Integer}
     */
    public Integer commentWhetherLike(Long userId, String id, int isLike) {
        //查找redis有无点赞数据
        String commentKey = RC.COMMENTS_INTERACT_KEY+id;
        String userHashKey = RC.COMMENT_LIKE_HASH_KEY+userId;
        Boolean hasKey = redisTemplate.opsForHash().hasKey(commentKey, userHashKey);
        if(hasKey&&isLike==1){
            //用户已点赞==>重复点赞
            throw new BusinessException(ErrorResult.likeError());
        }else if (!hasKey&&isLike==-1){
            //用户未点赞==>取消点赞
            throw new BusinessException(ErrorResult.disLikeError());
        }
        //进行正常点赞获取消点赞操作
        Integer likeCount = commentsApi.commentWhetherLike(id,isLike);
        //根据点赞类型填入或删除redis数据
        if (isLike==1){
            redisTemplate.opsForHash().put(commentKey,userHashKey,"1");
        }else {
            redisTemplate.opsForHash().delete(commentKey,userHashKey);
        }
        return likeCount;
    }
}
